{
  lib,
  stdenv,
  fetchurl,
  installShellFiles,
  pkg-config,

  # Optional dependencies
  enableApp ? with stdenv.hostPlatform; !isWindows && !isStatic,
  c-aresMinimal,
  libev,
  openssl,
  zlib,
  enableGetAssets ? false,
  libxml2,
  enableHpack ? false,
  jansson,
  enableHttp3 ? false,
  ngtcp2,
  nghttp3,
  enableJemalloc ? false,
  jemalloc,
  enablePython ? false,
  python3,
  ncurses,

  # Unit tests ; we have to set TZDIR, which is a GNUism.
  enableTests ? stdenv.hostPlatform.isGnu,
  cunit,
  tzdata,

  # downstream dependencies, for testing
  curl,
  libsoup_3,
}:

# Note: this package is used for bootstrapping fetchurl, and thus cannot use fetchpatch!
# All mutable patches (generated by GitHub or cgit) that are needed here
# should be included directly in Nixpkgs as files.

assert enableGetAssets -> enableApp;
assert enableHpack -> enableApp;
assert enableHttp3 -> enableApp;
assert enableJemalloc -> enableApp;

stdenv.mkDerivation rec {
  pname = "nghttp2";
  version = "1.67.1";

  src = fetchurl {
    url = "https://github.com/nghttp2/nghttp2/releases/download/v${version}/nghttp2-${version}.tar.bz2";
    hash = "sha256-37cg1CQ6eVBYn6JjI3i+te6a1ELpS3lLO44soowdfio=";
  };

  outputs = [
    "out"
    "dev"
    "lib"
    "doc"
    "man"
  ];

  nativeBuildInputs = [ pkg-config ] ++ lib.optionals enableApp [ installShellFiles ];

  buildInputs =
    lib.optionals enableApp [
      c-aresMinimal
      libev
      zlib
      openssl
    ]
    ++ lib.optionals enableGetAssets [ libxml2 ]
    ++ lib.optionals enableHpack [ jansson ]
    ++ lib.optionals enableJemalloc [ jemalloc ]
    ++ lib.optionals enableHttp3 [
      ngtcp2
      nghttp3
    ]
    ++ lib.optionals enablePython [ python3 ];

  enableParallelBuilding = true;

  configureFlags = [
    "--disable-examples"
    (lib.enableFeature enableApp "app")
    (lib.enableFeature enableHttp3 "http3")
  ];

  # Unit tests require CUnit and setting TZDIR environment variable
  doCheck = enableTests;
  nativeCheckInputs = lib.optionals enableTests [
    cunit
    tzdata
  ];
  preCheck = lib.optionalString enableTests ''
    export TZDIR=${tzdata}/share/zoneinfo
  '';

  # this could be accomplished by updateAutotoolsGnuConfigScriptsHook, but that causes infinite recursion
  # necessary for FreeBSD code path in configure
  postPatch = ''
    substituteInPlace ./config.guess --replace-fail /usr/bin/uname uname
  '';

  postInstall =
    lib.optionalString enableApp ''
      installShellCompletion --bash doc/bash_completion/{h2load,nghttp,nghttpd,nghttpx}
    ''
    + lib.optionalString (!enableApp) ''
      rm -r $out/bin
    ''
    + lib.optionalString enablePython ''
      patchShebangs $out/share/nghttp2
    '';

  passthru.tests = {
    inherit curl libsoup_3;
  };

  meta = {
    description = "HTTP/2 C library and tools";
    longDescription = ''
      nghttp2 is an implementation of the HyperText Transfer Protocol version 2 in C.
      The framing layer of HTTP/2 is implemented as a reusable C library. On top of that,
      we have implemented an HTTP/2 client, server and proxy. We have also developed
      load test and benchmarking tools for HTTP/2.
      An HPACK encoder and decoder are available as a public API.
      We have Python bindings of this library, but we do not have full code coverage yet.
      An experimental high level C++ library is also available.
    '';

    homepage = "https://nghttp2.org/";
    changelog = "https://github.com/nghttp2/nghttp2/releases/tag/v${version}";
    # News articles with changes summary can be found here: https://nghttp2.org/blog/archives/
    license = lib.licenses.mit;
    maintainers = with lib.maintainers; [ c0bw3b ];
    platforms = lib.platforms.all;
  };
}
